package i18n

import (
	"encoding/json"
	"fmt"
	"gitee.com/vrv_media/go-micro-framework/pkg/logger"
	"github.com/BurntSushi/toml"
	goI18n "github.com/nicksnyder/go-i18n/v2/i18n"
	"golang.org/x/text/language"
	"path/filepath"
	"strings"
	"sync"
)

type Translation struct {
	logger            logger.LoggerHelper
	defaultLanguage   string   // 默认语言
	supportLanguages  []string //支持的语言
	resourceDirection string   // 资源路径,资源的格式：XXX.语言.toml/json
	translations      []string // 加载的文件格式，根据resourceDirection和resourceType自动解析
	bundle            *goI18n.Bundle
	resourceType      ResourceType //文件类型，toml或者json
	once              sync.Once
}

func NewTranslation(defaultLanguage string, resourceDirection string, resourceType ResourceType) *Translation {
	if resourceType == "" {
		panic("resourceType cannot be empty")
	}
	if resourceDirection == "" {
		panic("resourceDirection cannot be empty")
	}
	if defaultLanguage == "" {
		defaultLanguage = "en"
	}
	trans := &Translation{
		logger:            logger.NewNameLogWithDefaultLog("Translation"),
		defaultLanguage:   defaultLanguage,
		resourceDirection: resourceDirection,
		resourceType:      resourceType,
	}
	trans.bundle = goI18n.NewBundle(language.English)
	switch resourceType {
	case ResourceTypeTOML:
		trans.bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
	case ResourceTypeJSON:
		trans.bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
	default:
		panic("not support resourceType")
	}
	trans.parsResourceDirection()
	return trans
}

func (t *Translation) TranslateMessageNoParam(messageId string, language string) string {
	return t.TranslateMessage(messageId, language, nil, 0)
}

func (t *Translation) TranslateMessageWithParam(messageId string, language string, param map[string]interface{}) string {
	return t.TranslateMessage(messageId, language, param, 0)
}

func (t *Translation) TranslateMessage(messageId string, language string, conf map[string]interface{}, pluralCount int) string {
	if language == "" || !t.supportLanguage(language) {
		language = t.defaultLanguage
	}
	localize := goI18n.NewLocalizer(t.bundle, language)
	localizeConfig := &goI18n.LocalizeConfig{
		MessageID: messageId,
	}
	if conf != nil {
		localizeConfig.TemplateData = conf
	}
	if pluralCount > 0 {
		localizeConfig.PluralCount = pluralCount
	}
	message, err := localize.Localize(localizeConfig)
	if err != nil {
		t.logger.ErrorF("translate message error: %v", err)
		return ""
	}
	return message
}

func (t *Translation) parsResourceDirection() {
	t.once.Do(func() {
		files, err := filepath.Glob(fmt.Sprintf("%s/*.%s", t.resourceDirection, t.resourceType))
		if err != nil {
			panic(fmt.Sprintf("glob resource files error: %v", err))
		}
		if len(files) == 0 {
			panic(fmt.Sprintf("no resource files found in %s", t.resourceDirection))
		}
		for _, file := range files {
			t.translations = append(t.translations, file)
			// 得到获取到的语言，根据文件格式，首先将类型去掉，获取.后面的字符
			lang := strings.TrimSuffix(filepath.Base(file), "."+string(t.resourceType))
			lang = lang[strings.LastIndex(lang, ".")+1:]
			t.supportLanguages = append(t.supportLanguages, lang)
		}
		// 检查defaultLanguage是否在支持的列表中
		defaultLanguageSupport := false
		for _, supportLanguage := range t.supportLanguages {
			if supportLanguage == t.defaultLanguage {
				defaultLanguageSupport = true
				break
			}
		}
		if !defaultLanguageSupport {
			panic(fmt.Sprintf("defaultLanguage not in resource list.DefaultLanguage:%s, supportLanguage:%v", t.defaultLanguage, t.supportLanguages))
		}
		// 加载语言
		for _, file := range t.translations {
			t.bundle.MustLoadMessageFile(file)
		}
	})
}

func (t *Translation) supportLanguage(lang string) bool {
	for _, supportLanguage := range t.supportLanguages {
		if supportLanguage == lang {
			return true
		}
	}
	return false
}

type ResourceType string

const (
	ResourceTypeTOML ResourceType = "toml"
	ResourceTypeJSON ResourceType = "json"
)
